//
// Created by z203 on 23-2-23.
//

#include "include/text_to_phone.h"
#include <cstdio>

#include <iostream>
#include <sndfile.h>
#include <cstring>
#include <numeric>
#include <vector>
#include <espeak-ng/speak_lib.h>
#include <map>
//#include <utf8.h>
#include <fstream>
#include <codecvt>
#include <locale>
#include <fstream>

void text_to_phone(const char *input, std::vector<int> &phonesId, const std::map<wchar_t, int> &phoneIdMap) {


    const std::string raw_phones = espeak_TextToPhonemes((const void **) &input, espeakCHARS_UTF8, 0x000002);
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wstringConvert;
    std::wstring raw_phones_wString = wstringConvert.from_bytes(raw_phones);
    for(size_t i = 0;i < raw_phones_wString.size();i++){
        if(phoneIdMap.find(raw_phones_wString[i]) != phoneIdMap.end()){
            phonesId.emplace_back(phoneIdMap.at(raw_phones_wString[i]));
            phonesId.emplace_back(0);
        }
    }
}

void load_phoneIdMap_v2(const char *phoneIdMap_filename, std::map<wchar_t, int> &phoneIdMap) {
    if (phoneIdMap_filename == nullptr) {
        return;
    }
    std::wifstream input_stream(phoneIdMap_filename);
    input_stream.imbue(std::locale("C.UTF-8"));
    std::vector<std::wstring> lines;
    wchar_t s[1000];
    while (input_stream.getline(s, 1000)) {
        lines.emplace_back(s);
    }

    for (size_t i = 0; i < lines.size(); i++) {
        wchar_t key = lines[i][0];

        std::wstring w_value = lines[i].substr(2, lines[i].size() - 2);

        int value = std::stoi(w_value);
        if (phoneIdMap.find(key) == phoneIdMap.end()) {
            phoneIdMap.emplace(key, value);
        }
    }
}

void load_phone_id_map(const char *phone_id_map_filename, std::map<std::string, int> &phone_id_map) {
    if (phone_id_map_filename != nullptr) {
        std::string content;
        FILE *phone_id_map_f = fopen(phone_id_map_filename, "r");
        char b[1000];
        while (fgets(b, 1000, phone_id_map_f) != nullptr) {
            content.append(b);
        }

        std::string k, v;

        size_t s = 0, e = 0;

        std::string *m = &k;
        for (size_t i = 0; i < content.size(); i++) {
            if (content[i] == '\t' || content[i] == '\n') {
                m->append(content, s, e - s);
                s = e + 1;
                if (m == &k) m = &v; else m = &k;

                if (content[i] == '\n') {
                    int vi = std::stoi(v);
                    phone_id_map.insert(std::make_pair(k, vi));
                    k.clear();
                    v.clear();
                }
            }
            e++;
        }
    }
}
